/**
 * 高德地图API加载器
 * 统一管理地图API的加载，避免重复加载，提高性能
 */

class MapLoader {
  constructor() {
    this.isLoading = false
    this.isLoaded = false
    this.loadPromise = null
    this.callbacks = []
    
    // 高德地图配置
    this.config = {
      version: '1.4.15',
      key: '93a2bc421fe24dc7e31c71276380b0b3',
      plugins: [
        'AMap.Scale',
        'AMap.ToolBar', 
        'AMap.Driving',
        'AMap.Geocoder',
        'AMap.MarkerCluster',
        'AMap.Heatmap'
      ]
    }
  }

  /**
   * 加载高德地图API
   * @returns {Promise} 返回Promise，解析为AMap对象
   */
  load() {
    // 如果已经加载完成，直接返回
    if (this.isLoaded && window.AMap) {
      console.log('高德地图API已加载，直接返回')
      return Promise.resolve(window.AMap)
    }

    // 如果正在加载，返回现有的Promise
    if (this.isLoading && this.loadPromise) {
      console.log('高德地图API正在加载中，等待完成')
      return this.loadPromise
    }

    // 开始加载
    console.log('开始加载高德地图API...')
    this.isLoading = true
    
    this.loadPromise = new Promise((resolve, reject) => {
      // 检查是否已经有脚本标签
      const existingScript = document.querySelector('script[src*="webapi.amap.com"]')
      if (existingScript) {
        console.log('发现已存在的地图API脚本')
        // 如果脚本已存在但AMap未定义，等待加载完成
        if (window.AMap) {
          this.onLoadSuccess(resolve)
          return
        } else {
          // 监听现有脚本的加载完成
          existingScript.addEventListener('load', () => {
            this.onLoadSuccess(resolve)
          })
          existingScript.addEventListener('error', () => {
            this.onLoadError(reject, new Error('现有地图API脚本加载失败'))
          })
          return
        }
      }

      // 创建新的脚本标签
      const script = document.createElement('script')
      script.type = 'text/javascript'
      script.async = true
      script.src = this.buildApiUrl()
      
      // 加载成功
      script.onload = () => {
        this.onLoadSuccess(resolve)
      }
      
      // 加载失败
      script.onerror = () => {
        this.onLoadError(reject, new Error('高德地图API脚本加载失败'))
      }
      
      // 添加到页面
      document.head.appendChild(script)
      
      // 设置超时
      setTimeout(() => {
        if (this.isLoading) {
          this.onLoadError(reject, new Error('高德地图API加载超时'))
        }
      }, 15000) // 15秒超时
    })

    return this.loadPromise
  }

  /**
   * 构建API URL
   * @returns {string} 完整的API URL
   */
  buildApiUrl() {
    const { version, key, plugins } = this.config
    const pluginStr = plugins.join(',')
    return `https://webapi.amap.com/maps?v=${version}&key=${key}&plugin=${pluginStr}`
  }

  /**
   * 加载成功处理
   * @param {Function} resolve Promise resolve函数
   */
  onLoadSuccess(resolve) {
    console.log('高德地图API加载成功')
    this.isLoading = false
    this.isLoaded = true
    
    // 验证AMap对象
    if (!window.AMap) {
      this.onLoadError(null, new Error('AMap对象未定义'))
      return
    }
    
    console.log('AMap版本:', window.AMap.version)
    resolve(window.AMap)
  }

  /**
   * 加载失败处理
   * @param {Function} reject Promise reject函数
   * @param {Error} error 错误对象
   */
  onLoadError(reject, error) {
    console.error('高德地图API加载失败:', error)
    this.isLoading = false
    this.isLoaded = false
    this.loadPromise = null
    
    if (reject) {
      reject(error)
    }
  }

  /**
   * 重置加载状态（用于重试）
   */
  reset() {
    console.log('重置地图API加载状态')
    this.isLoading = false
    this.isLoaded = false
    this.loadPromise = null
    
    // 移除现有脚本
    const existingScript = document.querySelector('script[src*="webapi.amap.com"]')
    if (existingScript) {
      existingScript.remove()
    }
    
    // 清理全局对象
    if (window.AMap) {
      delete window.AMap
    }
  }

  /**
   * 检查API是否可用
   * @returns {boolean} API是否可用
   */
  isAvailable() {
    return this.isLoaded && !!window.AMap
  }

  /**
   * 获取API状态信息
   * @returns {Object} 状态信息
   */
  getStatus() {
    return {
      isLoading: this.isLoading,
      isLoaded: this.isLoaded,
      isAvailable: this.isAvailable(),
      version: window.AMap?.version || null,
      config: this.config
    }
  }
}

// 创建单例实例
const mapLoader = new MapLoader()

// 导出加载函数和实例
export const loadAMap = () => mapLoader.load()
export const resetAMap = () => mapLoader.reset()
export const getAMapStatus = () => mapLoader.getStatus()
export default mapLoader
